package com.theexceptions.todo.view;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.theexceptions.todo.controller.SearchMapController;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

/**
 * An Activity that displays a user's locations in a mapview. Users can search
 * for new locations if they desire and can set them or existing ones to the
 * current task they are adding. Corresponds to the view: searchmaps.xml.
 * 
 * @author Justian Meyer
 */
public class SearchMapActivity extends MapActivity {

	private LocationItemizedOverlay itemizedOverlay;
	private MapView mapView;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		ProgressDialog dialog = ProgressDialog.show(this, "",
				"Loading. Please wait...", true);

		setContentView(R.layout.searchmaps);

		mapView = (MapView) findViewById(R.id.searchmapview);
		mapView.setBuiltInZoomControls(true);

		List<Overlay> mapOverlays = mapView.getOverlays();
		itemizedOverlay = SearchMapController.getAllLocationsItemizedOverlay(this);

		if (itemizedOverlay != null)
			mapOverlays.add(itemizedOverlay);

		mapView.postInvalidate(); // refresh
		
		dialog.cancel();
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	/**
	 * Searches for the location requested by the user when the search button is
	 * clicked. If a location is found, a new marker will be placed at its
	 * coordinates to be selected; otherwise, the user will be shown an error
	 * dialog.
	 * 
	 * @param view Button pressed
	 */
	public void mapSearchButtonClicked(View view) {
		EditText mapSearchEditText = (EditText) this.findViewById(R.id.mapSearchEditText);
		String searched = mapSearchEditText.getText().toString();

		Geocoder geocoder = new Geocoder(this, Locale.getDefault());
		List<Address> addresses;

		try {
			addresses = geocoder.getFromLocationName(searched, 5);

			// Display a loading dialog
			ProgressDialog dialog = ProgressDialog.show(this, "",
					"Loading. Please wait...", true);

			if (addresses.size() > 0) {

				List<Overlay> mapOverlays = mapView.getOverlays();
				LocationItemizedOverlay newOverlay;
				LocationItemizedOverlay allOverlay;

				// Use information from first found location
				Address a = addresses.get(0);
				double lat = a.getLatitude();
				double lon = a.getLongitude();

				// Get one overlay for new point and another for existing locs
				GeoPoint point = new GeoPoint((int) (lat * 1000000), (int) (lon * 1000000));
				newOverlay = SearchMapController.getNewLocationItemizedOverlay(searched, point, this);
				allOverlay = SearchMapController.getAllLocationsItemizedOverlay(this);

				// Clear the maps current list of overlays and apply new ones
				mapOverlays.clear();
				mapOverlays.add(newOverlay);
				if (allOverlay != null)
					mapOverlays.add(allOverlay);

				mapView.postInvalidate(); // refresh map

				MapController controller = mapView.getController();
				controller.setCenter(point);
				controller.setZoom(10);

				Toast.makeText(this, "Click the pin to confirm the location.", Toast.LENGTH_SHORT).show();

			} else {
				showNotFoundDialog(searched);
			}

			// Cancel the loading dialog
			dialog.cancel();

		} catch (IOException e) {
			Log.e("SearchMapActivity.mapSearchButtonClicked()", "IOException Occured", e);
		}
	}

	/**
	 * Displays a dialog stating that no locations can be found, given the
	 * user's input.
	 * 
	 * @param searched Address/Location
	 */
	private void showNotFoundDialog(String searched) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage("Location: \"" + searched + "\" could not be found. Please try another search.")
				.setCancelable(true)
				.setNeutralButton("Cancel", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						dialog.cancel();
					}
				});
		AlertDialog alert = builder.create();
		alert.show();
	}

}
